package com.mba.base;

import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.EnumMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.codehaus.jackson.map.DeserializationConfig.Feature;
import org.codehaus.jackson.map.ObjectMapper;

import com.mba.util.InvokeUtil;

import android.app.Activity;


public abstract class RequestJsonActivity extends Activity{
	private static final EnumMap<ActivitysType, RequestJson> requestJsons=new EnumMap<ActivitysType, RequestJsonActivity.RequestJson>(ActivitysType.class);
	private static final int THREAD_POOL_SIZE=10;
	private static final ThreadPoolExecutor executor=(ThreadPoolExecutor) Executors.newFixedThreadPool(THREAD_POOL_SIZE);
	public interface RequestJson{
		public void result(Object object);
	}
	public void request(RequestJson requestJson,RequestEntity requestEntity,RequestMethod method){
		requestJsons.put(requestEntity.requestType(), requestJson);
		switch (method) {
		case GET:
			requestGet(requestEntity);
			break;
		case POST:
			requestPost(requestEntity);
			break;
		}
	}
	public enum RequestMethod{
		POST,GET
	}
	private boolean isCancelRequest=false;
	/**请求数据接口*/
	private interface BackResult {
		public String url();
		public HttpEntity getEntity();
		public Class<?> backClass();
		public String getParam();
		public ActivitysType requestType();
	}
	
	public void cancelRequest(){
		isCancelRequest=true;
	}

	public static class RequestEntity implements BackResult{
		private String url=null;
		private String param;
		private String protocol;
		private HttpEntity httpEntity;
		private Class<?> clz;
		private ActivitysType requestType;

		public void setRequestType(ActivitysType requestType) {
			this.requestType = requestType;
		}
		public RequestEntity(Class<?> backClass) {
			this.clz=backClass;
		}

		public RequestEntity() {
		}
		

		@Override
		public String url() {
			return url.concat("/").concat(protocol);
		}

		@Override
		public HttpEntity getEntity() {
			return httpEntity;
		}

		@Override
		public Class<?> backClass() {
			return clz;
		}

		@Override
		public String getParam() {
			return param;
		}
		
		/**请求路径*/
		public void setURL(String url){
			this.url=url;
		}
		
		/**请求协议 如 http://127.0.0.1/login?userName=test&passWord=test 中 login为请求协议 "?" 后的则是参数 */
		public void setProtocol(String protocol){
			this.protocol=protocol;
		}
		
		/**传入对象需要实现setter/getter方法*/
		public void setParam(Object param){
			try {
				this.param=InvokeUtil.invokeObjtoString(param);
			} catch (IllegalArgumentException e) {
				e.printStackTrace();
			} catch (SecurityException e) {
				e.printStackTrace();
			} catch (InstantiationException e) {
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				e.printStackTrace();
			} catch (InvocationTargetException e) {
				e.printStackTrace();
			} catch (NoSuchMethodException e) {
				e.printStackTrace();
			}
		}
		
		/**请求参数*/
		public void setParam(String param){
			this.param=param;
		}
		
		/**请求参数*/
		public void setParam(Map<String,String> param){
			StringBuilder sb = new StringBuilder();
			boolean frist=true;
			for(Iterator<String> it = param.keySet().iterator();it.hasNext();){
				String key =  it.next();
				String value = param.get(key);
				if(frist){
					frist=false;
				}else{
					sb.append("&");
				}
				sb.append(key).append("=").append(value);
			}
			
			this.param=sb.toString();
		}
		
		/**传入HttpEntity*/
		public void setHttpEntity(HttpEntity httpEntity){
			this.httpEntity=httpEntity;
		}
		@Override
		public ActivitysType requestType() {
			// TODO Auto-generated method stub
			return requestType;
		}
	}
	
	private void requestPost(final BackResult backResult) {
		executor.submit(new Runnable() {
			@Override
			public void run() {
				Object obj = null;
				HttpPost request = new HttpPost(backResult.url());
				List<NameValuePair> p = new ArrayList<NameValuePair>();
				
				String[] params = backResult.getParam().split("&");
						
				for (String param:params) {
					String[] keyValue=param.split("=");
					String key = keyValue[0]!=null?keyValue[0]:null;
					if(key==null)
						continue;
					p.add(new BasicNameValuePair(key, keyValue[1]!=null?keyValue[1]:""));
				}
				
				HttpEntity entity = null;
				try {
					entity = new UrlEncodedFormEntity(p, "UTF-8");
					request.setEntity(entity);
					HttpParams httpParameters = new BasicHttpParams();
					int timeoutConnection = 40000;
					HttpConnectionParams.setConnectionTimeout(httpParameters,
							timeoutConnection);
					int timeoutSocket = 40000;
					HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket);
					HttpClient client = new DefaultHttpClient(httpParameters);
					if(!isCancelRequest){
						HttpResponse response = client.execute(request);
						if(!isCancelRequest){
							if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
								if(backResult.backClass()!=null){
								ObjectMapper mapper = new ObjectMapper();
								/**忽略新字段*/
								mapper.getDeserializationConfig().set(Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);
								Object object=mapper.readValue(response.getEntity().getContent(),backResult.backClass());
								requestJsons.get(backResult.requestType()).result(object);
								}else{
									requestJsons.get(backResult.requestType()).result(new String(read(response.getEntity().getContent())));
								}
							}else{
							}
						}else{
							isCancelRequest=false;
						}
					}else{
						isCancelRequest=false;
					}
				} catch (Exception e) {
				}finally{
					if(isCancelRequest)
						isCancelRequest=true;
				}
				if(isCancelRequest)
					isCancelRequest=true;
			}
		});
	}
	
	private void requestGet(final BackResult backResult){
		executor.submit(new Runnable() {
			@Override
			public void run() {
				Object obj=null;
				URL requestUrl;
				try {
					requestUrl = new URL(backResult.url().concat("?").concat(backResult.getParam()));
					if(!isCancelRequest){
						HttpURLConnection urlConnection = (HttpURLConnection) requestUrl
								.openConnection();
						urlConnection.setRequestMethod("GET");
						urlConnection.setConnectTimeout(5 * 1000);
						if(!isCancelRequest){
							if (urlConnection.getResponseCode() == 200) {
								Object object=null;
								if(backResult.backClass()!=null){
								ObjectMapper mapper = new ObjectMapper();
								/**忽略新字段*/
								mapper.getDeserializationConfig().set(Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);
								object=mapper.readValue(urlConnection.getInputStream(),backResult.backClass());
								}else{
									object=new String(read(urlConnection.getInputStream()));
								}
								requestJsons.get(backResult.requestType()).result(object);
								
							}else{
							}
						}else{
							isCancelRequest=false;
						}
					}else{
						isCancelRequest=false;
					}
				} catch (Exception e) {
				}finally{
					if(isCancelRequest)
						isCancelRequest=true;
				}
				if(isCancelRequest)
					isCancelRequest=true;
			}
		});
	}

	public byte[] read(InputStream inputStream) throws Exception {
		ByteArrayOutputStream arrayBuffer = new ByteArrayOutputStream();
		byte[] b = new byte[1024];
		int len = -1;
		while ((len = inputStream.read(b)) != -1) {
			arrayBuffer.write(b, 0, len);
		}
		inputStream.close();
		arrayBuffer.close();
		return arrayBuffer.toByteArray();
	}
}
